﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using FreedomERP.Models;
using System.Collections;
using System.Data.Objects;
using System.Text;
using FreedomERP.Comm;
using FreedomERP.Comm.DB;
using FreedomERP.Comm.Utils;
using FreedomERP.Models.Inv;
using FreedomERP.Dao.Inv;
using FreedomERP.Dao.Bd;
using FreedomERP.Dao.Bd.Impl;

namespace FreedomERP.Dao.Inv.Impl
{
    public class InvShortageOrderDAOImpl : IInvShortageOrderDAO
    {
        FreedomERPEntities dbEntities = new FreedomERPEntities();

        /// <summary>
        /// 根据参数获取欠货单信息
        /// </summary>
        /// <param name="paggingParams"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public DAOResult<InvShortageOrder> QueryShortageOrderPaggingByParam(PagingParams paggingParams, out int totalCount)
        {
            Hashtable filters = paggingParams.filters;

            //where
            List<ObjectParameter> paramList = new List<ObjectParameter>();
            StringBuilder sbWhere = new StringBuilder();
            if (filters["FCustomerIdParam"] != null && !filters["FCustomerIdParam"].ToString().Equals(""))
            {
                sbWhere.Append("it.FCustomerId = @FCustomerIdParam and ");
                ObjectParameter param = new ObjectParameter("FCustomerIdParam", filters["FCustomerIdParam"].ToString());
                paramList.Add(param);
            }
            if (filters["FSendOrderNumParam"] != null && !filters["FSendOrderNumParam"].ToString().Equals(""))
            {
                sbWhere.Append("it.FSendOrderNumber like @FSendOrderNumParam and ");
                ObjectParameter param = new ObjectParameter("FSendOrderNumParam", "%" + filters["FSendOrderNumParam"].ToString() + "%");
                paramList.Add(param);
            }
            if (filters["FBillDateFrom"] != null && !filters["FBillDateFrom"].ToString().Equals(""))
            {
                sbWhere.Append("it.FBillDate between @FBillDateFrom and @FBillDateTo and ");
                ObjectParameter param = new ObjectParameter("FBillDateFrom", DateUtils.ParseStringToDateTime(filters["FBillDateFrom"].ToString()));
                paramList.Add(param);
                string FBillDateTo = "";
                if (filters["FBillDateTo"] != null && !filters["FBillDateTo"].ToString().Equals(""))
                {
                    FBillDateTo = filters["FBillDateTo"].ToString();
                }
                else
                {
                    FBillDateTo = DateUtils.GetCurDateFormat("yyyy/MM/dd HH:mm:ss");
                }
                ObjectParameter paramT = new ObjectParameter("FBillDateTo", DateUtils.ParseStringToDateTime(FBillDateTo));
                paramList.Add(paramT);
            }
            if (filters["FStatusIdParam"] != null && !filters["FStatusIdParam"].ToString().Equals(""))
            {
                sbWhere.Append("it.FStatus=@FStatusIdParam and ");
                ObjectParameter param = new ObjectParameter("FStatusIdParam", filters["FStatusIdParam"].ToString());
                paramList.Add(param);
            }
            if (filters["FProductIdParam"] != null && !filters["FProductIdParam"].ToString().Equals(""))
            {
                String prodId = filters["FProductIdParam"].ToString();
                List<String> sortageDetaiList = (from sortageDetai in dbEntities.InvShortageOrderDetail where sortageDetai.FProductId == prodId select sortageDetai.FParentId).ToList();
                String inValues = "{";
                foreach (var value in sortageDetaiList)
                {
                    inValues += "'" + value + "'" + ",";
                }
                if (inValues.Contains(","))
                {
                    inValues = inValues.Substring(0, inValues.Length - 1);
                }
                inValues += "}";
                if (sortageDetaiList.Count == 0)
                {
                    inValues = "{''}";
                }
                sbWhere.Append(" it.FId in " + inValues + " and ");
            }

            sbWhere.Append("1=1");

            //order by
            StringBuilder sbOrder = new StringBuilder();
            sbOrder.Append("it.FModifyTime desc");

            ObjectParameter[] objParameters = new ObjectParameter[paramList.Count];
            int c = 0;
            foreach (ObjectParameter paramTemp in paramList)
            {
                objParameters[c] = paramTemp;
                c++;
            }

            var query = dbEntities.InvShortageOrder.Where(sbWhere.ToString(), objParameters).OrderBy(sbOrder.ToString());

            totalCount = query.Count();

            List<InvShortageOrder> list = query.Skip(paggingParams.Start).Take(paggingParams.Limit).ToList();

            return new DAOResult<InvShortageOrder>(true, "", list);
        }


        /// <summary>
        /// 修改欠货单状态
        /// </summary>
        /// <param name="fId"></param>
        /// <param name="modifierId"></param>
        /// <param name="statusID"></param>
        /// <returns></returns>
        public DAOResult<String> updateShortageOrderStatus(String fId, String modifierId, String statusID)
        {
            InvShortageOrder dbShortageOrder = null;
            List<InvShortageOrder> dbShortageOrders = (from sortageOrder in dbEntities.InvShortageOrder where sortageOrder.FId == fId select sortageOrder).ToList();
            if (dbShortageOrders.Count <= 0)
            {
                return new DAOResult<String>(false, "该欠货单不存在，无法修改状态。", null);
            }
            else
            {
                dbShortageOrder = dbShortageOrders.First();
                IBdAccountDao accoutDao = new BdAccountDaoImpl();
                BdAccount accout = accoutDao.GetAccountByFId(modifierId);
                if (accout == null)
                {
                    return new DAOResult<String>(false, "该用户不存在，无法修改状态。", null);
                }
                else
                {
                    dbShortageOrder.FModifierId = modifierId;
                    dbShortageOrder.FModifyTime = DateTime.Now;

                }
                IBdCategoryDao categoryDao = new BdCategoryDaoImpl();
                BdCategory dbCategory = categoryDao.getCategoryByFId(statusID);
                if (dbCategory == null)
                {
                    return new DAOResult<String>(false, "该状态Id不存在，无法修改状态。", null);
                }
                else
                {
                    dbShortageOrder.FStatus = statusID;
                }
                dbEntities.SaveChanges();
                List<String> restultSet = new List<String>();
                restultSet.Add(dbShortageOrder.FId);
                return new DAOResult<String>(true, "", restultSet);

            }
        }


        /// <summary>
        /// 根据参数获取欠货单详情信息
        /// </summary>
        /// <param name="paggingParams"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public DAOResult<InvShortageOrderDetail> QueryShortageOrderDetailPaggingByParam(PagingParams paggingParams, out int totalCount)
        {
            Hashtable filters = paggingParams.filters;
            Expression<Func<InvShortageOrderDetail, bool>> predicate = PredicateExtensions.True<InvShortageOrderDetail>();
            if (filters["Fid"] != null || !ConstData.EMPTY_STRING.Equals(filters["Fid"].ToString()))
            {
                String fId = filters["Fid"].ToString();
                predicate = predicate.And(ordertDetail => ordertDetail.FParentId == fId);
            }
            var query = dbEntities.InvShortageOrderDetail.Where(predicate);
            totalCount = query.Count();
            List<InvShortageOrderDetail> orderDetails = query.OrderByDescending(ordertDetail => ordertDetail.FProductId).Skip(paggingParams.Start).Take(paggingParams.Limit).ToList();
            return new DAOResult<InvShortageOrderDetail>(true, "", orderDetails);
        }


        /// <summary>
        /// 修改欠货单详情
        /// </summary>
        /// <param name="fId"></param>
        /// <param name="fParentId"></param>
        /// <param name="returnNum"></param>
        /// <returns></returns>
        public DAOResult<String> UpdateShortageOrderDetail(String fId, String fParentId, String returnNum, String modifierId)
        {
            InvShortageOrder shortageOrder = null;
            List<InvShortageOrder> shortageOrders = (from shortageOrd in dbEntities.InvShortageOrder where shortageOrd.FId == fParentId select shortageOrd).ToList();
            if (shortageOrders.Count <= 0)
            {
                return new DAOResult<String>(false, "该缺货单详情所属的缺货单不存在，无法修改。", null);
            }
            shortageOrder = shortageOrders.First();
            InvShortageOrderDetail shortageOrderDetail = null;
            List<InvShortageOrderDetail> orderDetails = (from orderDetail in dbEntities.InvShortageOrderDetail where orderDetail.FId.Equals(fId) select orderDetail).ToList();
            if (orderDetails.Count <= 0)
            {
                return new DAOResult<String>(false, "该缺货单详情不存在，无法修改。", null);
            }
            shortageOrderDetail = orderDetails.First();
            if (shortageOrderDetail.FNumber < Int64.Parse(returnNum))
            {
                return new DAOResult<String>(false, "归还数量大于缺货数量，无法修改。", null);
            }
            else
            {
                shortageOrderDetail.FReturnNumber = Int64.Parse(returnNum);
            }
            List<InvShortageOrderDetail> orderDetailList = (from orderDetail in dbEntities.InvShortageOrderDetail where orderDetail.FParentId.Equals(fParentId) select orderDetail).ToList();
            bool allReturned = true;
            foreach (var orderDetail in orderDetailList)
            {
                if (orderDetail.FId.Equals(fId))
                {
                    if (shortageOrderDetail.FNumber > Int64.Parse(returnNum))
                    {
                        allReturned = false;
                        break;
                    }
                }
                else
                {
                    if (orderDetail.FNumber > orderDetail.FReturnNumber)
                    {
                        allReturned = false;
                        break;
                    }
                }
            }

            if (allReturned)
            {
                String statusId = null;
                List<BdCategory> statusCategorys = (from statCate in dbEntities.BdCategory where statCate.FOrgunitId == shortageOrder.FOrgunitId && statCate.FType.Equals(ConstData.CATEGORY_INV_SHORTAGE_STATUS_TYPE) && statCate.FName.Equals(ConstData.CATEGORY_INV_SHORTAGE_STATUS_INVALID) select statCate).ToList();
                if (statusCategorys.Count <= 0)
                {
                    return new DAOResult<String>(false, "缺货单状态信息，无法修改。", null);
                }
                statusId = statusCategorys.First().FId;
                shortageOrder.FStatus = statusId;
            }
            shortageOrder.FModifierId = modifierId;
            shortageOrder.FModifyTime = DateTime.Now;
            dbEntities.SaveChanges();
            List<String> resultSet = new List<String>();
            resultSet.Add(shortageOrder.FId);
            return new DAOResult<String>(true, "", resultSet);
        }

        /// <summary>
        /// 添加缺货单
        /// </summary>
        /// <author>梁建东</author>
        /// <param name="shortageOrder"></param>
        public void addShortageOrder(InvShortageOrder shortageOrder)
        {
            dbEntities.InvShortageOrder.AddObject(shortageOrder);
        }

        /// <summary>
        /// 保存修改
        /// </summary>
        /// <author>梁建东</author>
        /// <returns></returns>
        public void Save()
        {
            dbEntities.SaveChanges();
        }

        /// <summary>
        /// 根据FId获取缺货单
        /// 作者：梁建东
        /// </summary>
        public InvShortageOrder GetShortageOrderByFId(String FId)
        {
            InvShortageOrder shortageOrder = dbEntities.InvShortageOrder.FirstOrDefault(ro => ro.FId == FId);
            return shortageOrder;
        }


        /// <summary>
        /// 为送货单创建欠货单（没有提交事务）
        /// </summary>
        /// <param name="shortageOrderNew"></param>
        /// <param name="creatorId"></param>
        /// <param name="FNumber"></param>
        public void createShortageOrderOfSendOrder(FreedomERPEntities dbEntities,InvShortageOrder shortageOrderNew, string creatorId, out string FNumber)
        {
            InvShortageOrder shortageOrder = new InvShortageOrder();
            shortageOrder.FId = GuidUtils.getGuid();
            shortageOrder.FNumber = ConstData.SHORTAGE_ORDER_NUMBER_HEAD + DateUtils.GetCurDateFormat("yyyyMMddHHmmss");
            shortageOrder.FName = shortageOrder.FNumber;
            shortageOrder.FBillDate = shortageOrderNew.FBillDate;
            shortageOrder.FCreateTime = DateUtils.GetCurDate();
            shortageOrder.FCreatorId = creatorId;
            shortageOrder.FModifyTime = DateUtils.GetCurDate();
            shortageOrder.FModifierId = creatorId;
            shortageOrder.FApproveTime = DateUtils.GetCurDate();
            shortageOrder.FApproverId = creatorId;
            shortageOrder.FOrgunitId = shortageOrderNew.FOrgunitId;
            shortageOrder.FSendOrderID = shortageOrderNew.FSendOrderID;
            shortageOrder.FSendOrderNumber = shortageOrderNew.FSendOrderNumber;
            shortageOrder.FCustomerId = shortageOrderNew.FCustomerId;
            shortageOrder.FRemark = "";

            shortageOrder.FStatus = shortageOrderNew.FStatus;

            if (shortageOrderNew.InvShortageOrderDetail != null)
            {
                foreach (InvShortageOrderDetail shortageOrderDetailNew in shortageOrderNew.InvShortageOrderDetail)
                {
                    InvShortageOrderDetail detail = new InvShortageOrderDetail();
                    detail.FId = GuidUtils.getGuid();
                    detail.FProductId = shortageOrderDetailNew.FProductId;
                    detail.FNumber = shortageOrderDetailNew.FNumber;
                    detail.FRemark = shortageOrderDetailNew.FRemark;

                    shortageOrder.InvShortageOrderDetail.Add(detail);
                }
            }
            dbEntities.InvShortageOrder.AddObject(shortageOrder);
            FNumber = shortageOrder.FNumber;
        }
    }
}